package mystruct

import (
	"io"
	"fmt"
    "time"
    "crypto/aes"
    "crypto/rand"
    "crypto/cipher"
    "encoding/base64"
    "crypto/sha256"
)

func Encrypt(plaintext string, key []byte) (string, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}

	ciphertext := make([]byte, aes.BlockSize+len(plaintext))
	iv := ciphertext[:aes.BlockSize]
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		return "", err
	}

	cipher.NewCFBEncrypter(block, iv).XORKeyStream(ciphertext[aes.BlockSize:], []byte(plaintext))

	return base64.URLEncoding.EncodeToString(ciphertext), nil
}

func Decrypt(ciphertext string, key []byte) (decrypted string, err error) {
	defer func() {
        if r := recover(); r != nil {
			err = fmt.Errorf("decryption panic: %v", r)
		}
    }()
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}

	decodedCiphertext, err := base64.URLEncoding.DecodeString(ciphertext)
	if err != nil {
		return "", err
	}

	iv := decodedCiphertext[:aes.BlockSize]
	decodedCiphertext = decodedCiphertext[aes.BlockSize:]

	cipher.NewCFBDecrypter(block, iv).XORKeyStream(decodedCiphertext, decodedCiphertext)

	return string(decodedCiphertext), nil
}

func GenerateAESKey() ([]byte, error) {
	key := make([]byte, 32) // 32 bytes for AES-256
	if _, err := rand.Read(key); err != nil {
		return nil, err
	}
	return key, nil
}

func GenerateEncryptedString(account string) string {
	timestamp := time.Now().Unix()
	data := fmt.Sprintf("%d%s", timestamp, account)
	hash := sha256.New()
	hash.Write([]byte(data))
	encryptedBytes := hash.Sum(nil)
	encryptedString := fmt.Sprintf("%x", encryptedBytes)
	return encryptedString
}
